package com.authstr.auth.shiro;

import com.authstr.auth.jwt.JwtUtil;
import com.authstr.auth.jwt.ShiroJwtToken;
import com.authstr.auth.service.inter.UserAuthService;
import com.authstr.auth.service.imip.UserAuthServiceImpl;
import com.authstr.basic.util.ToolUtil;
import com.authstr.model.base.BaseUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义realm
 */
public class ShiroRealm extends AuthorizingRealm {

    /**
     * 使用jwt代替原生token
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof ShiroJwtToken;
    }

        /**
         * 执行授权逻辑
         * @param principalCollection
         * @return
         */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        UserAuthService shiroFactory = UserAuthServiceImpl.me();
        ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
        List<Long> roleList = shiroUser.getRoleList();
//
        Set<String> permissionSet = new HashSet<>();
        Set<String> roleNameSet = new HashSet<>(shiroUser.getRoleNames());
        for (Long roleId : roleList) {
            List<String> permissions = shiroFactory.getMenuUrlByRoleId(roleId);
            if (permissions != null) {
                for (String permission : permissions) {
                    if (ToolUtil.isNotEmpty(permission)) {
                        permissionSet.add(permission);
                    }
                }
            }
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionSet);
        info.addRoles(roleNameSet);
        return info;
    }

    /**
     * 执行登录认证逻辑
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UserAuthService shiroFactory = UserAuthServiceImpl.me();
        String token = (String)authenticationToken.getCredentials();
        String account = JwtUtil.getAccount(token);

        BaseUser user = shiroFactory.user(account);

        ShiroUser shiroUser = shiroFactory.shiroUser(user);
        if(user == null) {
            throw new UnknownAccountException("账号不存在");
        }

        if(!JwtUtil.verify(token, user.getAccount(), user.getPassword())) {
            throw new CredentialsException("账号/密码错误");
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(shiroUser, token,getName());
        return simpleAuthenticationInfo;

    }


}
